package cn.springcloud.fix.demo.io;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import java.util.concurrent.ThreadPoolExecutor;

public class ReadState implements HandlerState {

    private SelectionKey selectionKey;

    @Override
    public void changeState(Handler h) {
        h.setState(new WriteState());
    }

    @Override
    public void handle(Handler h, SelectionKey sk, SocketChannel sc, ThreadPoolExecutor pool) throws IOException {
        this.selectionKey = sk;
        // non-blocking下不可用Readers，因为Readers不支持non-blocking
        byte[] arr = new byte[1024];
        ByteBuffer buf = ByteBuffer.wrap(arr);

        int numBytes = sc.read(buf); // 读取字符串
        if (numBytes == -1) {
            System.out.println("[Warning!] A client has been closed.");
            h.closeChannel();
            return;
        }
        String str = new String(arr); // 将读取到的byte內容转为字符串类型
        if ((str != null) && !str.equals(" ")) {
            h.setState(new WriteState()); // 改变状态(READING->WORKING)
            pool.execute(new WorkerThread(h, str)); // do process in worker thread
            System.out.println(sc.socket().getRemoteSocketAddress().toString() + " > " + str);
        }
    }

    synchronized void process(Handler h, String str) {
        h.setState(new WriteState()); // 改变状态(WORKING->SENDING)
        this.selectionKey.interestOps(SelectionKey.OP_WRITE); // 通过key改变通道注册的事件
        this.selectionKey.selector().wakeup(); // 使一个阻塞住的selector操作立即返回
    }

    /*
     * 工作者线程
     */
    class WorkerThread implements Runnable {

        Handler h;
        String str;

        public WorkerThread(Handler h, String str) {
            this.h = h;
            this.str = str;
        }

        @Override
        public void run() {
            process(h, str);
        }
    }
}
